/*
 * Copyright (c) 2023 Cshoo Org. All Rights Reserved.
 */

package org.cshoo.tattoo.authorize.domain.service;

import lombok.extern.slf4j.Slf4j;
import org.cshoo.tattoo.authorize.domain.po.Role;
import org.cshoo.tattoo.authorize.domain.po.RoleAuthorityRelation;
import org.cshoo.tattoo.authorize.domain.po.RoleButtonRelation;
import org.cshoo.tattoo.authorize.domain.po.RoleMenuRelation;
import org.cshoo.tattoo.authorize.domain.repository.IRoleAuthorityRelationRepository;
import org.cshoo.tattoo.authorize.domain.repository.IRoleButtonRelationRepository;
import org.cshoo.tattoo.authorize.domain.repository.IRoleMenuRelationRepository;
import org.cshoo.tattoo.authorize.domain.repository.IRoleRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 杨翼
 * @since 1.0
 */
@Slf4j
@Service
public class RoleService {

    @Resource
    private IRoleRepository roleRepository;

    @Resource
    private IRoleAuthorityRelationRepository roleAuthorityRelationRepository;

    @Resource
    private IRoleMenuRelationRepository roleMenuRelationRepository;

    @Resource
    private IRoleButtonRelationRepository roleButtonRelationRepository;

    /**
     * 根据角色名称查询角色
     *
     * @param name 名称
     * @return 角色
     */
    public Role findRoleByName(String name) {
        return roleRepository.findRoleByName(name);
    }

    /**
     * 查询角色
     *
     * @param userId 用户id
     * @return 角色
     */
    public List<Role> findRolesByUserId(Long userId) {
        log.info("userId:{}", userId);
        return roleRepository.findRolesByUserId(userId);
    }

    /**
     * 添加一个角色
     *
     * @param role 角色数据
     */
    public void addRole(Role role) {
        roleRepository.save(role);
    }

    /**
     * 修改一个角色
     *
     * @param role 角色
     */
    public void updateRole(Role role) {
        log.info("role:{}", role);
        roleRepository.save(role);
    }

    /**
     * 删除角色
     *
     * @param ids 角色id列表
     */
    public void deleteRoles(List<Long> ids) {
        for (Long id : ids) {
            roleRepository.deleteById(id);
        }
    }

    /**
     * 根据群组id查询角色
     *
     * @param groupId 群组id
     * @return 角色
     */
    public List<Role> findRolesByGroupId(Long groupId) {
        log.info("groupId:{}", groupId);
        return roleRepository.findRolesByGroupId(groupId);
    }

    /**
     * 查询所有角色
     *
     * @return 角色
     */
    public Page<Role> findAllRoles(int pageNum, int pageSize) {
        PageRequest pageRequest = PageRequest.of(pageNum, pageSize);
        return roleRepository.findAll(pageRequest);
    }

    /**
     * 取消权限
     *
     * @param roleId       角色id
     * @param authorityIds 权限id
     */
    public void cancelAuthorities(Long roleId, List<Long> authorityIds) {
        roleAuthorityRelationRepository.deleteByRoleIdAndAuthorityIdIsIn(roleId, authorityIds);
    }

    /**
     * 给角色授权
     *
     * @param roleId       角色id
     * @param authorityIds 权限id
     */
    public void authorize(Long roleId, List<Long> authorityIds) {
        authorityIds.forEach(aid -> {
            RoleAuthorityRelation roleAuthorityRelation = new RoleAuthorityRelation();
            roleAuthorityRelation.setRoleId(roleId);
            roleAuthorityRelation.setAuthorityId(aid);
            roleAuthorityRelationRepository.save(roleAuthorityRelation);
        });
    }

    /**
     * 根据角色名称模糊查询角色列表
     * 这里只显示前10个
     *
     * @param name 名称
     * @return 角色
     */
    public List<Role> findRolesByNameLike(String name) {
        Pageable pageable = PageRequest.of(0, 10);
        return roleRepository.findRolesByName(name, pageable);
    }

    /**
     * 授予菜单权限
     *
     * @param roleId 角色id
     * @param menuId 菜单id
     */
    public void authorizeMenu(Long roleId, Long menuId) {
        log.info("roleId:{},menuId:{}", roleId, menuId);
        RoleMenuRelation roleMenuRelation = new RoleMenuRelation();
        roleMenuRelation.setMenuId(menuId);
        roleMenuRelation.setRoleId(roleId);
        roleMenuRelationRepository.save(roleMenuRelation);
    }

    /**
     * 取消菜单权限
     *
     * @param roleId 角色id
     * @param menuId 菜单id
     */
    public void cancelMenuAuthority(Long roleId, Long menuId) {
        roleMenuRelationRepository.deleteByRoleIdAndMenuId(roleId, menuId);
    }

    /**
     * 授予按钮权限
     *
     * @param roleId   角色id
     * @param buttonId 按钮id
     */
    public void authorizeButton(Long roleId, Long buttonId) {
        RoleButtonRelation roleButtonRelation = new RoleButtonRelation();
        roleButtonRelation.setRoleId(roleId);
        roleButtonRelation.setButtonId(buttonId);
        roleButtonRelationRepository.save(roleButtonRelation);
    }

    /**
     * 取消按钮权限
     *
     * @param roleId   角色id
     * @param buttonId 按钮id
     */
    public void cancelButtonAuthority(Long roleId, Long buttonId) {
        log.info("roleId:{},buttonId:{}", roleId, buttonId);
        roleButtonRelationRepository.deleteByRoleIdAndButtonId(roleId, buttonId);
    }
}
